import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Observable;
import java.util.StringTokenizer;

import org.apache.commons.net.telnet.TelnetClient;
import org.apache.commons.net.telnet.TelnetNotificationHandler;
import org.apache.commons.net.telnet.SimpleOptionHandler;
import org.apache.commons.net.telnet.EchoOptionHandler;
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
import org.apache.commons.net.telnet.InvalidTelnetOptionException;

public class TelnetRead extends Observable implements Runnable, TelnetNotificationHandler{
	private TelnetClient tc;
	
	public TelnetRead(TelnetClient tc, Telnet tr){
		this.tc = tc;
		this.addObserver(tr);
	}
	
	public void connect(String ip, int port) throws Exception{
		TerminalTypeOptionHandler ttopt = 	new TerminalTypeOptionHandler("VT100", false, false, true, false);
		EchoOptionHandler echoopt = 		new EchoOptionHandler(true, false, true, false);
		SuppressGAOptionHandler gaopt = 	new SuppressGAOptionHandler(true, true, true, true);

		try {
			tc.addOptionHandler(ttopt);
			tc.addOptionHandler(echoopt);
			tc.addOptionHandler(gaopt);
		} catch (InvalidTelnetOptionException e) {
			System.err.println("Error registering option handlers: " + e.getMessage());
		}
		
		try {
			tc.connect(ip, port);			
			Thread reader = new Thread(this);
			tc.registerNotifHandler(this);
			reader.start();
		} catch (IOException e) {
			System.err.println("Exception while connecting:" + e.getMessage());
			System.exit(1);
		}	
	}
	
	public void run() {
		InputStream instr = tc.getInputStream();

		try {
			byte[] buff = new byte[1024];
			int ret_read = 0;
			char stream;
			do {
				ret_read = instr.read(buff);
				if (ret_read > 0) {
					System.out.print(new String(buff, 0, ret_read));
					stream = new String(buff, 0, ret_read).charAt(0);
					handleInput(stream);
				}
			} while (ret_read >= 0);
		} catch (IOException e) {
			System.err.println("Exception while reading socket:" + e.getMessage());
		}

		try {
			tc.disconnect();
		} catch (IOException e) {
			System.err.println("Exception while closing telnet:" + e.getMessage());
		}
	}
	
	private void handleInput(char stream) {
		setChanged();
		notifyObservers(stream);	
	}

	public void receivedNegotiation(int negotiation_code, int option_code) {
		String command = null;
		if (negotiation_code == TelnetNotificationHandler.RECEIVED_DO) {
			command = "DO";
		} else if (negotiation_code == TelnetNotificationHandler.RECEIVED_DONT) {
			command = "DONT";
		} else if (negotiation_code == TelnetNotificationHandler.RECEIVED_WILL) {
			command = "WILL";
		} else if (negotiation_code == TelnetNotificationHandler.RECEIVED_WONT) {
			command = "WONT";
		}
		//System.out.println("Received " + command + " for option code " + option_code);
	}
	
	
}